package com.lb.pdm;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * 简化版代码生成器
 * 不依赖数据库连接，直接生成基础的代码结构
 * 
 * @author pdm
 * @since 2024-01-15
 */
public class CodeGeneratorSimple {

    /**
     * 项目路径配置
     */
    private static final String PROJECT_PATH = System.getProperty("user.dir");
    private static final String JAVA_PATH = PROJECT_PATH + "/src/main/java";
    private static final String MAPPER_XML_PATH = PROJECT_PATH + "/src/main/resources/mapper";

    /**
     * 包名配置
     */
    private static final String PARENT_PACKAGE = "com.lb.pdm";
    private static final String ENTITY_PACKAGE = PARENT_PACKAGE + ".entity";
    private static final String MAPPER_PACKAGE = PARENT_PACKAGE + ".mapper";
    private static final String SERVICE_PACKAGE = PARENT_PACKAGE + ".service";
    private static final String SERVICE_IMPL_PACKAGE = PARENT_PACKAGE + ".service.impl";
    private static final String CONTROLLER_PACKAGE = PARENT_PACKAGE + ".controller";

    /**
     * 作者信息
     */
    private static final String AUTHOR = "pdm";

    /**
     * 表名和对应的实体类名
     */
    private static final String[][] TABLE_CLASS_MAPPING = {
        {"sys_user", "SysUser", "系统用户"},
        {"person_info", "PersonInfo", "人员信息"},
        {"household_info", "HouseholdInfo", "户籍信息"},
        {"household_member", "HouseholdMember", "户籍成员"},
        {"birth_registration", "BirthRegistration", "出生登记"},
        {"household_transfer", "HouseholdTransfer", "户口迁移"},
        {"family_reunion", "FamilyReunion", "家庭团聚"},
        {"floating_population", "FloatingPopulation", "流动人口"},
        {"key_personnel", "KeyPersonnel", "重点人员"},
        {"certificate_info", "CertificateInfo", "证件信息"},
        {"certificate_application", "CertificateApplication", "证件申请"},
        {"sys_dict", "SysDict", "数据字典"},
        {"operation_log", "OperationLog", "操作日志"}
    };

    public static void main(String[] args) {
        System.out.println("=== 简化版代码生成器 ===");
        System.out.println("生成路径：" + JAVA_PATH);
        System.out.println("开始生成代码...");

        try {
            // 创建目录
            createDirectories();
            
            // 生成所有表的代码
            for (String[] mapping : TABLE_CLASS_MAPPING) {
                String tableName = mapping[0];
                String className = mapping[1];
                String comment = mapping[2];
                
                generateEntityClass(className, comment);
                generateMapperInterface(className, comment);
                generateMapperXml(className, tableName, comment);
                generateServiceInterface(className, comment);
                generateServiceImpl(className, comment);
                generateController(className, comment);
                
                System.out.println("✓ 已生成 " + className + " 相关代码");
            }
            
            System.out.println("\n=== 代码生成完成！===");
            System.out.println("生成的文件位置：");
            System.out.println("- 实体类：" + JAVA_PATH + "/com/lb/pdm/entity/");
            System.out.println("- Mapper：" + JAVA_PATH + "/com/lb/pdm/mapper/");
            System.out.println("- Service：" + JAVA_PATH + "/com/lb/pdm/service/");
            System.out.println("- Controller：" + JAVA_PATH + "/com/lb/pdm/controller/");
            System.out.println("- Mapper XML：" + MAPPER_XML_PATH + "/");
            
        } catch (Exception e) {
            System.err.println("代码生成失败：" + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 创建必要的目录
     */
    private static void createDirectories() {
        List<String> dirs = Arrays.asList(
            JAVA_PATH + "/com/lb/pdm/entity",
            JAVA_PATH + "/com/lb/pdm/mapper", 
            JAVA_PATH + "/com/lb/pdm/service",
            JAVA_PATH + "/com/lb/pdm/service/impl",
            JAVA_PATH + "/com/lb/pdm/controller",
            MAPPER_XML_PATH
        );
        
        for (String dir : dirs) {
            new File(dir).mkdirs();
        }
    }

    /**
     * 生成实体类
     */
    private static void generateEntityClass(String className, String comment) throws IOException {
        String filePath = JAVA_PATH + "/com/lb/pdm/entity/" + className + ".java";
        
        StringBuilder content = new StringBuilder();
        content.append("package ").append(ENTITY_PACKAGE).append(";\n\n");
        content.append("import com.baomidou.mybatisplus.annotation.*;\n");
        content.append("import lombok.Data;\n");
        content.append("import lombok.EqualsAndHashCode;\n");
        content.append("import lombok.experimental.Accessors;\n");
        content.append("import io.swagger.v3.oas.annotations.media.Schema;\n\n");
        content.append("import java.io.Serializable;\n");
        content.append("import java.time.LocalDateTime;\n\n");
        
        content.append("/**\n");
        content.append(" * ").append(comment).append("\n");
        content.append(" *\n");
        content.append(" * @author ").append(AUTHOR).append("\n");
        content.append(" * @since ").append(java.time.LocalDate.now()).append("\n");
        content.append(" */\n");
        content.append("@Data\n");
        content.append("@EqualsAndHashCode(callSuper = false)\n");
        content.append("@Accessors(chain = true)\n");
        content.append("@TableName(\"").append(toUnderlineCase(className)).append("\")\n");
        content.append("@Schema(name = \"").append(className).append("\", description = \"").append(comment).append("\")\n");
        content.append("public class ").append(className).append(" implements Serializable {\n\n");
        content.append("    private static final long serialVersionUID = 1L;\n\n");
        content.append("    @Schema(description = \"主键ID\")\n");
        content.append("    @TableId(value = \"id\", type = IdType.AUTO)\n");
        content.append("    private Long id;\n\n");
        content.append("    @Schema(description = \"创建时间\")\n");
        content.append("    @TableField(value = \"create_time\", fill = FieldFill.INSERT)\n");
        content.append("    private LocalDateTime createTime;\n\n");
        content.append("    @Schema(description = \"更新时间\")\n");
        content.append("    @TableField(value = \"update_time\", fill = FieldFill.INSERT_UPDATE)\n");
        content.append("    private LocalDateTime updateTime;\n\n");
        content.append("    // TODO: 添加其他字段\n\n");
        content.append("}\n");
        
        writeToFile(filePath, content.toString());
    }

    /**
     * 生成Mapper接口
     */
    private static void generateMapperInterface(String className, String comment) throws IOException {
        String filePath = JAVA_PATH + "/com/lb/pdm/mapper/" + className + "Mapper.java";
        
        StringBuilder content = new StringBuilder();
        content.append("package ").append(MAPPER_PACKAGE).append(";\n\n");
        content.append("import ").append(ENTITY_PACKAGE).append(".").append(className).append(";\n");
        content.append("import com.baomidou.mybatisplus.core.mapper.BaseMapper;\n");
        content.append("import org.apache.ibatis.annotations.Mapper;\n\n");
        
        content.append("/**\n");
        content.append(" * ").append(comment).append(" Mapper 接口\n");
        content.append(" *\n");
        content.append(" * @author ").append(AUTHOR).append("\n");
        content.append(" * @since ").append(java.time.LocalDate.now()).append("\n");
        content.append(" */\n");
        content.append("@Mapper\n");
        content.append("public interface ").append(className).append("Mapper extends BaseMapper<").append(className).append("> {\n\n");
        content.append("}\n");
        
        writeToFile(filePath, content.toString());
    }

    /**
     * 生成Mapper XML
     */
    private static void generateMapperXml(String className, String tableName, String comment) throws IOException {
        String filePath = MAPPER_XML_PATH + "/" + className + "Mapper.xml";
        
        StringBuilder content = new StringBuilder();
        content.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        content.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n");
        content.append("<mapper namespace=\"").append(MAPPER_PACKAGE).append(".").append(className).append("Mapper\">\n\n");
        content.append("    <!-- 通用查询映射结果 -->\n");
        content.append("    <resultMap id=\"BaseResultMap\" type=\"").append(ENTITY_PACKAGE).append(".").append(className).append("\">\n");
        content.append("        <id column=\"id\" property=\"id\" />\n");
        content.append("        <result column=\"create_time\" property=\"createTime\" />\n");
        content.append("        <result column=\"update_time\" property=\"updateTime\" />\n");
        content.append("        <!-- TODO: 添加其他字段映射 -->\n");
        content.append("    </resultMap>\n\n");
        content.append("    <!-- 通用查询结果列 -->\n");
        content.append("    <sql id=\"Base_Column_List\">\n");
        content.append("        id, create_time, update_time\n");
        content.append("        <!-- TODO: 添加其他字段 -->\n");
        content.append("    </sql>\n\n");
        content.append("</mapper>\n");
        
        writeToFile(filePath, content.toString());
    }

    /**
     * 生成Service接口
     */
    private static void generateServiceInterface(String className, String comment) throws IOException {
        String filePath = JAVA_PATH + "/com/lb/pdm/service/" + className + "Service.java";
        
        StringBuilder content = new StringBuilder();
        content.append("package ").append(SERVICE_PACKAGE).append(";\n\n");
        content.append("import ").append(ENTITY_PACKAGE).append(".").append(className).append(";\n");
        content.append("import com.baomidou.mybatisplus.extension.service.IService;\n\n");
        
        content.append("/**\n");
        content.append(" * ").append(comment).append(" 服务类\n");
        content.append(" *\n");
        content.append(" * @author ").append(AUTHOR).append("\n");
        content.append(" * @since ").append(java.time.LocalDate.now()).append("\n");
        content.append(" */\n");
        content.append("public interface ").append(className).append("Service extends IService<").append(className).append("> {\n\n");
        content.append("}\n");
        
        writeToFile(filePath, content.toString());
    }

    /**
     * 生成Service实现类
     */
    private static void generateServiceImpl(String className, String comment) throws IOException {
        String filePath = JAVA_PATH + "/com/lb/pdm/service/impl/" + className + "ServiceImpl.java";
        
        StringBuilder content = new StringBuilder();
        content.append("package ").append(SERVICE_IMPL_PACKAGE).append(";\n\n");
        content.append("import ").append(ENTITY_PACKAGE).append(".").append(className).append(";\n");
        content.append("import ").append(MAPPER_PACKAGE).append(".").append(className).append("Mapper;\n");
        content.append("import ").append(SERVICE_PACKAGE).append(".").append(className).append("Service;\n");
        content.append("import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\n");
        content.append("import org.springframework.stereotype.Service;\n\n");
        
        content.append("/**\n");
        content.append(" * ").append(comment).append(" 服务实现类\n");
        content.append(" *\n");
        content.append(" * @author ").append(AUTHOR).append("\n");
        content.append(" * @since ").append(java.time.LocalDate.now()).append("\n");
        content.append(" */\n");
        content.append("@Service\n");
        content.append("public class ").append(className).append("ServiceImpl extends ServiceImpl<").append(className).append("Mapper, ").append(className).append("> implements ").append(className).append("Service {\n\n");
        content.append("}\n");
        
        writeToFile(filePath, content.toString());
    }

    /**
     * 生成Controller
     */
    private static void generateController(String className, String comment) throws IOException {
        String filePath = JAVA_PATH + "/com/lb/pdm/controller/" + className + "Controller.java";
        
        StringBuilder content = new StringBuilder();
        content.append("package ").append(CONTROLLER_PACKAGE).append(";\n\n");
        content.append("import ").append(ENTITY_PACKAGE).append(".").append(className).append(";\n");
        content.append("import ").append(SERVICE_PACKAGE).append(".").append(className).append("Service;\n");
        content.append("import org.springframework.beans.factory.annotation.Autowired;\n");
        content.append("import org.springframework.web.bind.annotation.*;\n");
        content.append("import io.swagger.v3.oas.annotations.Operation;\n");
        content.append("import io.swagger.v3.oas.annotations.tags.Tag;\n\n");
        content.append("import java.util.List;\n\n");
        
        content.append("/**\n");
        content.append(" * ").append(comment).append(" 前端控制器\n");
        content.append(" *\n");
        content.append(" * @author ").append(AUTHOR).append("\n");
        content.append(" * @since ").append(java.time.LocalDate.now()).append("\n");
        content.append(" */\n");
        content.append("@RestController\n");
        content.append("@RequestMapping(\"/").append(toHyphenCase(className)).append("\")\n");
        content.append("@Tag(name = \"").append(comment).append("\", description = \"").append(comment).append("管理\")\n");
        content.append("public class ").append(className).append("Controller {\n\n");
        content.append("    @Autowired\n");
        content.append("    private ").append(className).append("Service ").append(toLowerCamelCase(className)).append("Service;\n\n");
        content.append("    @GetMapping(\"/list\")\n");
        content.append("    @Operation(summary = \"获取").append(comment).append("列表\")\n");
        content.append("    public List<").append(className).append("> list() {\n");
        content.append("        return ").append(toLowerCamelCase(className)).append("Service.list();\n");
        content.append("    }\n\n");
        content.append("    @GetMapping(\"/{id}\")\n");
        content.append("    @Operation(summary = \"根据ID获取").append(comment).append("\")\n");
        content.append("    public ").append(className).append(" getById(@PathVariable Long id) {\n");
        content.append("        return ").append(toLowerCamelCase(className)).append("Service.getById(id);\n");
        content.append("    }\n\n");
        content.append("    @PostMapping\n");
        content.append("    @Operation(summary = \"新增").append(comment).append("\")\n");
        content.append("    public boolean save(@RequestBody ").append(className).append(" ").append(toLowerCamelCase(className)).append(") {\n");
        content.append("        return ").append(toLowerCamelCase(className)).append("Service.save(").append(toLowerCamelCase(className)).append(");\n");
        content.append("    }\n\n");
        content.append("    @PutMapping\n");
        content.append("    @Operation(summary = \"更新").append(comment).append("\")\n");
        content.append("    public boolean updateById(@RequestBody ").append(className).append(" ").append(toLowerCamelCase(className)).append(") {\n");
        content.append("        return ").append(toLowerCamelCase(className)).append("Service.updateById(").append(toLowerCamelCase(className)).append(");\n");
        content.append("    }\n\n");
        content.append("    @DeleteMapping(\"/{id}\")\n");
        content.append("    @Operation(summary = \"删除").append(comment).append("\")\n");
        content.append("    public boolean removeById(@PathVariable Long id) {\n");
        content.append("        return ").append(toLowerCamelCase(className)).append("Service.removeById(id);\n");
        content.append("    }\n\n");
        content.append("}\n");
        
        writeToFile(filePath, content.toString());
    }

    /**
     * 写入文件
     */
    private static void writeToFile(String filePath, String content) throws IOException {
        File file = new File(filePath);
        file.getParentFile().mkdirs();
        
        try (FileWriter writer = new FileWriter(file)) {
            writer.write(content);
        }
    }

    /**
     * 驼峰转下划线
     */
    private static String toUnderlineCase(String str) {
        return str.replaceAll("([A-Z])", "_$1").toLowerCase().replaceFirst("^_", "");
    }

    /**
     * 驼峰转连字符
     */
    private static String toHyphenCase(String str) {
        return str.replaceAll("([A-Z])", "-$1").toLowerCase().replaceFirst("^-", "");
    }

    /**
     * 转换为小驼峰
     */
    private static String toLowerCamelCase(String str) {
        return str.substring(0, 1).toLowerCase() + str.substring(1);
    }
}